/**
 * Copyright 2008 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kiff.entity;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Version;

import kiff.enumerator.RoleStatus;
import kiff.security.Principal;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * Role Entity.
 * @author Adam
 * @version $Id: Role.java 73 2008-12-02 06:28:25Z a.ruggles $
 */
@Entity @Table(name = "roles")
@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Role implements Principal, CoreEntity<Integer>, UpdateAware<Role>, Comparable<Role> {
	/**
	 * Serial Version UID.
	 */
	private static final long serialVersionUID = -238910479349306202L;

	/**
	 * The description of the role.
	 */
	private String description;

	/**
	 * The unique identifier.
	 */
	private Integer id;

	/**
	 * The unique name for the role.
	 */
	private String name;

	/**
	 * The status of the role.
	 */
	private RoleStatus status;

    /**
     * The version for optimistic concurrency control.
     */
    private Integer version;

    /**
     * Default Constructor.
     */
    public Role() { }

    /**
     * Constructs a Role with a name, description and status.
     * @param name The name of the role.
     * @param description The description of the role.
     * @param status The status of the role.
     */
    public Role(final String name, final String description, final RoleStatus status) {
    	this.name = name;
    	this.description = description;
    	this.status = status;
    }

    /**
     * {@inheritDoc}
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
	public int compareTo(final Role role) {
		if (this.name == null || role == null || role.getName() == null) {
			return -1;
		}
		return this.name.compareTo(role.getName());
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (!(obj instanceof Role)) {
			return false;
		}
		Role rhs = (Role) obj;
		return new EqualsBuilder()
			.append(name, rhs.getName())
			.isEquals();
	}

	/**
	 * Returns the description.
	 * @return the description to return.
	 */
	@Lob
	public String getDescription() {
		return description;
	}

	/**
	 * {@inheritDoc}
	 * @see kiff.entity.CoreEntity#getId()
	 */
	@Id @GeneratedValue(strategy = GenerationType.AUTO)
	public Integer getId() {
		return id;
	}

	/**
	 * Returns the name.
	 * @return the name to return.
	 */
	@Column(length = 50, unique = true, nullable = false)
	public String getName() {
		return name;
	}

	/**
	 * Returns the status.
	 * @return The status to return.
	 */
    @org.hibernate.annotations.Type(
            type = "kiff.enumerator.GenericEnumUserType",
            parameters = {
                    @org.hibernate.annotations.Parameter(
                            name  = "enumClass",               
                            value = "kiff.enumerator.RoleStatus"),
                    @org.hibernate.annotations.Parameter(
                            name  = "identifierMethod",
                            value = "getValue"),
                    @org.hibernate.annotations.Parameter(
                            name  = "valueOfMethod",
                            value = "fromValue")
            }
    )
    @Basic(optional = false)
	public RoleStatus getStatus() {
		return status;
	}

	/**
	 * Returns the version.
	 * @return the version to return.
	 */
	@Version
	public Integer getVersion() {
		return version;
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return new HashCodeBuilder(3, 37)
			.append(name)
			.toHashCode();
	}

	/**
	 * Sets the description.
	 * @param description the description to set.
	 */
	public void setDescription(final  String description) {
		this.description = description;
	}

	/**
	 * {@inheritDoc}
	 * @see kiff.entity.CoreEntity#setId(java.io.Serializable)
	 */
	public void setId(final Integer id) {
		this.id = id;
	}

	/**
	 * Sets the name.
	 * @param name the name to set.
	 */
	public void setName(final  String name) {
		this.name = name;
	}

	/**
	 * Sets the status.
	 * @param status the status to set.
	 */
	public void setStatus(final RoleStatus status) {
		this.status = status;
	}

	/**
	 * Sets the version.
	 * @param version the version to set.
	 */
	public void setVersion(final Integer version) {
		this.version = version;
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return new ToStringBuilder(this)
			.append("id", id)
			.append("name", name)
			.append("description", description)
			.append("status", status)
			.toString();
	}

	/**
	 * {@inheritDoc}
	 * @see kiff.entity.UpdateAware#update(java.lang.Object)
	 */
	public void update(final Role entity) {
		if (entity.getName() != null) {
			this.name = entity.getName();
		}
		if (entity.getDescription() != null) {
			this.description = entity.getDescription();
		}
		if (entity.getStatus() != null) {
			this.status = entity.getStatus();
		}
	}

}
